#!/usr/bin/env bash

# Decrypts and mounts EncFS directory and opens in file manager.
# This does not support mounting multiple dirs at once. Feel free to improve
# though.
#
# Requirements:
#   - sh/bash/ksh/zsh etc.
#   - encfs
#   - sudo or doas
#
# Usage:
#   You can run it with a directory:
#     $ this_script.sh ~/somesecretoremptydir
#   Or alternatively, put it on ~/.bash_aliases or "source" it:
#     $ . this_script.sh
#   or
#     $ source this_script.sh
#   Either of the above will add a "encfs_mount" alias. Then:
#     $ encfs_mount /path/to/somedir
#   Never manually change files in this directory. Only put files in the mounted
#   directory (e.g. /media/username/EncFS). If this encrypted directory does not
#   exist, EncFS will prompt you to create it. Don't forget to unmount when done
#   accessing files. Either use the eject button on your file manager sidebar
#   (you should see it if your system is configured) or run:
#     $ fusermount -u /media/username/EncFS
#   or
#     $ umount /media/username/EncFS
#
# Tested with: FreeBSD sh+bash+zsh; Void Linux sh+bash.
# License: CC0
# Compatibility note: "function" omitted, brackets added for sh.
_func_encfs_mount() {
  if [ -z "$1" ]; then echo "error: provide an empty dir or already encrypted dir"; return 1; fi
  local d="/media/$USER/EncFS"
  # Compatibility note: '>/dev/null 2>&1' works with sh to silence any output.
  if mount | grep /media/user/EncFS >/dev/null 2>&1; then
    read -r -p "Another directory is mounted on $d. Do you want to unmount? [y/N] " answer
    # Compatibility note: explicitly used || instead of ~ for sh
    if [ "$answer" == 'y' ] || [ "$answer" == 'Y' ]; then
      fusermount -u "$d" >/dev/null 2>&1 || umount "$d"
    else
      return 3
    fi
  fi
  local subin=sudo
  type doas >/dev/null 2>&1 && subin=doas
  if ! type encfs >/dev/null 2>&1; then echo "error: encfs not installed"; return 2; fi
  if [ ! -d "$d" ]; then
    if [ -w "$(dirname "$d")" ]; then
      # Since /media/$USER is writable, we can just make a directory
      mkdir -p "$d"
    else
      # Create the /media/$USER dir only, so that it can be chowned before
      # creating the final dir (and hence automatically owning final dir)
      $subin mkdir -p "$(dirname "$d")"
      # So that user can create files without permission issues
      $subin chown "$USER" "$(dirname "$d")"
      mkdir -p "$d"
    fi
  fi
  if [ -n "$DISPLAY" ] && ( type xdg-open >/dev/null 2>&1 || type gio >/dev/null 2>&1 ); then
    encfs "$1" "$d" && echo -e "Unencrypted files mounted on $d"
    ( xdg-open "$d" >/dev/null 2>&1 || gio open "$d" >/dev/null 2>&1 ) && echo -e "Don't forget to unmount $d after use"'!! '"Either unmount 'EncFS' from your file manager sidebar or run 'fusermount -u $d' or 'umount $d'"
  else
    echo "will be mounting on $d... Ctrl+C later to unmount..."
    encfs -f "$1" "$d"
  fi
}
# Compatibility note: Only function doesn't make it executable on sh as bash
# does, so code is separated on a function and it is called from this alias and
# it works.
alias encfs_mount='_func_encfs_mount'
# When run directly passing an argument, without "source"-ing it first.
if [ -n "$1" ]; then
  _func_encfs_mount "$1"
fi
